--[[
    上海宝钢 10.46.101.1:448
            10.46.101.3:448

    先检查retCode节点值是否为26012,
    是,表示失败;
    不是再检查Result节点值:
    7表示成功
    6或8表示失败
    其它表示处理中
]]
require("apm_core")
require("ApmXml")
local httpUtil = require("ApmHttpUtil")

local G_DEBUG = true

if G_DEBUG == false then
    function logDebug(fmt,...) end
    function logInfo(fmt,...) end
    function logWarn(fmt,...) end
    function logError(fmt,...) end
    function logFatal(fmt,...) end
end

local KRED='\x1B[0;31m'
local KSALMON='\x1B[1;31m'
local KGREEN='\x1B[0;32m'
local KLIMEGREEN='\x1B[1;32m'
local KYELLOW='\x1B[0;33m'
local KORANGE='\x1B[0;34m'
local KBLUE='\x1B[1;34m'
local KMAGENTA='\x1B[0;35m'
local KPINK='\x1B[1;35m'
local KCYAN='\x1B[0;36m'
local RESET='\x1B[0m'

local G_RESP_SUCC = 0
local G_RESP_FAIL = -1
local dict_transtype = {}

local function parseIp(ip)
    local _, _, value = string.find(ip, "(%d+.%d+)$")
    return value == nil and "" or value
end

local function protocol_detect(s_payload)
    if s_payload == nil then return false end

    local t_xml_tree = ApmXml.load(s_payload, "UTF-8")

    if ApmXml.getValue(t_xml_tree, "/ICBCYH") ~= nil then
        return t_xml_tree
    else
        return nil
    end
end

--- 解析请求
-- return
-- true: 解析成功; false: 解析失败
local function parse_req(t_xml_tree)
    -- 交易类型
    local s_transtype = ApmXml.getValue(t_xml_tree, "/ICBCYH/opReq/opName/text()")
    local s_transtype_name
    if s_transtype ~= nil then
        s_transtype = string.trim(s_transtype)
        s_transtype_name = dict_transtype[s_transtype]
        if s_transtype_name == nil then s_transtype_name = s_transtype end
    end

    -- 流水号
    local s_flowno = ApmXml.getValue(t_xml_tree, "/ICBCYH/opReq/ReqParam/PackageID/text()")
    return s_transtype, s_transtype_name, s_flowno
end

--- 解析响应
-- return
-- true: 解析成功; false: 解析失败
local function parse_resp(t_xml_tree)
    -- 返回码
    local s_rspcode = G_RESP_SUCC
    local s_rspcode_string = ApmXml.getValue(t_xml_tree, "/ICBCYH/opRep/opResult/retCode/text()")
    if s_rspcode_string == "26012" then
        s_rspcode = G_RESP_FAIL
    else
        s_rspcode_string = ApmXml.getValue(t_xml_tree, "/ICBCYH/opRep/opResult/Result/text()")
        if s_rspcode_string == "6" or s_rspcode_string == "8" then
            s_rspcode = G_RESP_FAIL
        end
    end

    -- 返回信息
    local s_rspmsg = ApmXml.getValue(t_xml_tree, "/ICBCYH/opRep/opResult/Bank_Rem/text()")

    return s_rspcode, s_rspcode_string, s_rspmsg
end

--- main
function post_analysis()
    local ApmData = require("ApmData")
    if ApmData.getL7Proto() ~= 80 then return end
    if ApmData.getMsgType() ~= 1 then return end

    local s_transtype
    local s_transtype_name
    local s_flowno
    local s_rspcode
    local s_rspcode_string
    local s_rspmsg

    local s_xml_req
    local t_kv = httpUtil.getParams(ApmData)
    if t_kv ~= nil then
        local s_xml_req = t_kv["reqData"]
        if s_xml_req ~= nil then
            s_xml_req = string.trim(s_xml_req)
            local t_xml_tree = protocol_detect(s_xml_req)
            if t_xml_tree ~= nil then
                s_transtype, s_transtype_name, s_flowno = parse_req(t_xml_tree)
            end
        end
    end

    local s_resp = ApmData.getField("response.http.body.1", 1)
    if s_resp ~= nil then
        local t_kv = httpUtil.parseParams(s_resp)
        if t_kv ~= nil then
            local s_xml_resp = t_kv["reqData"]
            if s_xml_resp ~= nil then
                s_xml_resp = string.trim(s_xml_resp)
                local t_xml_tree = protocol_detect(s_xml_resp)
                if t_xml_tree ~= nil then
                    s_rspcode, s_rspcode_string, s_rspmsg = parse_resp(t_xml_tree)
                end
            end
        end
    end

    if s_transtype == nil then
        logInfo("s_transtype is nil REQ:["..KRED.."%s"..RESET.."]", s_xml_req)
    elseif s_rspcode_string == nil then
        logInfo("s_rspcode_string is nil RESP:["..KBLUE.."%s"..RESET.."]", s_resp)
    else
        ApmData.replaceField("transaction.type_code", s_transtype)
        ApmData.replaceField("transaction.type_name", s_transtype_name)
--        ApmData.replaceField("transaction.title", s_transtype_name)

        ApmData.replaceField("response.code", s_rspcode)
        ApmData.replaceField("response.code_string", s_rspcode_string)

        if s_rspmsg ~= nil then
            ApmData.replaceField("response.error_message", s_rspmsg)
        end

        if s_flowno ~= nil then
            ApmData.replaceField("transaction.code", s_flowno)
        end

        logInfo("(%s:%d->%s:%d) name:%s|seq:%s|ret:%s|%s|%s",
            ApmData.getSrcIp(),
            ApmData.getSrcPort(),
            parseIp(ApmData.getDstIp()),
            ApmData.getDstPort(),
            s_transtype,
            s_flowno,
            s_rspcode,
            s_rspcode_string,
            s_rspmsg
        )
    end

    return
end
--101.1:448
--101.3:448
--v1.0.1
